﻿using System.Diagnostics.Contracts;
using System.Reactive.Concurrency;
using System.Reactive.Subjects;
#if !SILVERLIGHT
using System.Runtime.Remoting.Lifetime;
#endif
#if !WINDOWS_PHONE
using System.Threading;
#endif

namespace System.Reactive.Linq
{
	public static partial class Observable
	{
		public static IObservable<int> Range(int start, int count)
		{
			Contract.Requires((start + count) - 1L <= int.MaxValue, null, "(start + count) - 1L <= int.MaxValue");
			Contract.Requires(count >= 0, null, "count >= 0");
			Contract.Ensures(Contract.Result<IObservable<int>>() != null, null, "Contract.Result<IObservable<int>>() != null");
			return null;
		}

		public static IObservable<int> Range(int start, int count, IScheduler scheduler)
		{
			Contract.Requires((start + count) - 1L <= int.MaxValue, null, "(start + count) - 1L <= int.MaxValue");
			Contract.Requires(count >= 0, null, "count >= 0");
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Ensures(Contract.Result<IObservable<int>>() != null, null, "Contract.Result<IObservable<int>>() != null");
			return null;
		}

		public static IObservable<TSource> RefCount<TSource>(this IConnectableObservable<TSource> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IObservable<TSource>>() != null, null, "Contract.Result<IObservable<TSource>>() != null");
			return null;
		}

#if !SILVERLIGHT
		public static IObservable<TSource> Remotable<TSource>(this IObservable<TSource> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IObservable<TSource>>() != null, null, "Contract.Result<IObservable<TSource>>() != null");
			return null;
		}

		public static IObservable<TSource> Remotable<TSource>(this IObservable<TSource> source, ILease lease)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IObservable<TSource>>() != null, null, "Contract.Result<IObservable<TSource>>() != null");
			return null;
		}
#endif

		public static IObservable<TSource> Repeat<TSource>(this IObservable<TSource> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IObservable<TSource>>() != null, null, "Contract.Result<IObservable<TSource>>() != null");
			return null;
		}

		public static IObservable<TResult> Repeat<TResult>(TResult value)
		{
			Contract.Ensures(Contract.Result<IObservable<TResult>>() != null, null, "Contract.Result<IObservable<TResult>>() != null");
			return null;
		}

		public static IObservable<TSource> Repeat<TSource>(this IObservable<TSource> source, int repeatCount)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(repeatCount >= 0, null, "repeatCount >= 0");
			Contract.Ensures(Contract.Result<IObservable<TSource>>() != null, null, "Contract.Result<IObservable<TSource>>() != null");
			return null;
		}

		public static IObservable<TResult> Repeat<TResult>(TResult value, int repeatCount)
		{
			Contract.Requires(repeatCount >= 0, null, "repeatCount >= 0");
			Contract.Ensures(Contract.Result<IObservable<TResult>>() != null, null, "Contract.Result<IObservable<TResult>>() != null");
			return null;
		}

		public static IObservable<TResult> Repeat<TResult>(TResult value, IScheduler scheduler)
		{
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Ensures(Contract.Result<IObservable<TResult>>() != null, null, "Contract.Result<IObservable<TResult>>() != null");
			return null;
		}

		public static IObservable<TResult> Repeat<TResult>(TResult value, int repeatCount, IScheduler scheduler)
		{
			Contract.Requires(repeatCount >= 0, null, "repeatCount >= 0");
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Ensures(Contract.Result<IObservable<TResult>>() != null, null, "Contract.Result<IObservable<TResult>>() != null");
			return null;
		}

		public static IConnectableObservable<TSource> Replay<TSource>(this IObservable<TSource> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IConnectableObservable<TSource>>() != null, null, "Contract.Result<IConnectableObservable<TSource>>() != null");
			return null;
		}

		public static IObservable<TResult> Replay<TSource, TResult>(this IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(selector != null, null, "selector != null");
			Contract.Ensures(Contract.Result<IObservable<TResult>>() != null, null, "Contract.Result<IObservable<TResult>>() != null");
			return null;
		}

		public static IConnectableObservable<TSource> Replay<TSource>(this IObservable<TSource> source, int bufferSize)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(bufferSize >= 0, null, "bufferSize >= 0");
			Contract.Ensures(Contract.Result<IConnectableObservable<TSource>>() != null, null, "Contract.Result<IConnectableObservable<TSource>>() != null");
			return null;
		}

		public static IConnectableObservable<TSource> Replay<TSource>(this IObservable<TSource> source, IScheduler scheduler)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Ensures(Contract.Result<IConnectableObservable<TSource>>() != null, null, "Contract.Result<IConnectableObservable<TSource>>() != null");
			return null;
		}

		public static IConnectableObservable<TSource> Replay<TSource>(this IObservable<TSource> source, TimeSpan window)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(window >= TimeSpan.Zero, null, "window >= TimeSpan.Zero");
			Contract.Ensures(Contract.Result<IConnectableObservable<TSource>>() != null, null, "Contract.Result<IConnectableObservable<TSource>>() != null");
			return null;
		}

		public static IObservable<TResult> Replay<TSource, TResult>(this IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector, int bufferSize)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(selector != null, null, "selector != null");
			Contract.Requires(bufferSize >= 0, null, "bufferSize >= 0");
			Contract.Ensures(Contract.Result<IObservable<TResult>>() != null, null, "Contract.Result<IObservable<TResult>>() != null");
			return null;
		}

		public static IObservable<TResult> Replay<TSource, TResult>(this IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector, IScheduler scheduler)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(selector != null, null, "selector != null");
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Ensures(Contract.Result<IObservable<TResult>>() != null, null, "Contract.Result<IObservable<TResult>>() != null");
			return null;
		}

		public static IObservable<TResult> Replay<TSource, TResult>(this IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector, TimeSpan window)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(selector != null, null, "selector != null");
			Contract.Requires(window >= TimeSpan.Zero, null, "window >= TimeSpan.Zero");
			Contract.Ensures(Contract.Result<IObservable<TResult>>() != null, null, "Contract.Result<IObservable<TResult>>() != null");
			return null;
		}

		public static IConnectableObservable<TSource> Replay<TSource>(this IObservable<TSource> source, int bufferSize, IScheduler scheduler)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(bufferSize >= 0, null, "bufferSize >= 0");
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Ensures(Contract.Result<IConnectableObservable<TSource>>() != null, null, "Contract.Result<IConnectableObservable<TSource>>() != null");
			return null;
		}

		public static IConnectableObservable<TSource> Replay<TSource>(this IObservable<TSource> source, int bufferSize, TimeSpan window)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(bufferSize >= 0, null, "bufferSize >= 0");
			Contract.Requires(window >= TimeSpan.Zero, null, "window >= TimeSpan.Zero");
			Contract.Ensures(Contract.Result<IConnectableObservable<TSource>>() != null, null, "Contract.Result<IConnectableObservable<TSource>>() != null");
			return null;
		}

		public static IConnectableObservable<TSource> Replay<TSource>(this IObservable<TSource> source, TimeSpan window, IScheduler scheduler)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(window >= TimeSpan.Zero, null, "window >= TimeSpan.Zero");
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Ensures(Contract.Result<IConnectableObservable<TSource>>() != null, null, "Contract.Result<IConnectableObservable<TSource>>() != null");
			return null;
		}

		public static IObservable<TResult> Replay<TSource, TResult>(this IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector, int bufferSize, IScheduler scheduler)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(selector != null, null, "selector != null");
			Contract.Requires(bufferSize >= 0, null, "bufferSize >= 0");
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Ensures(Contract.Result<IObservable<TResult>>() != null, null, "Contract.Result<IObservable<TResult>>() != null");
			return null;
		}

		public static IObservable<TResult> Replay<TSource, TResult>(this IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector, int bufferSize, TimeSpan window)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(selector != null, null, "selector != null");
			Contract.Requires(bufferSize >= 0, null, "bufferSize >= 0");
			Contract.Requires(window >= TimeSpan.Zero, null, "window >= TimeSpan.Zero");
			Contract.Ensures(Contract.Result<IObservable<TResult>>() != null, null, "Contract.Result<IObservable<TResult>>() != null");
			return null;
		}

		public static IObservable<TResult> Replay<TSource, TResult>(this IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector, TimeSpan window, IScheduler scheduler)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(selector != null, null, "selector != null");
			Contract.Requires(window >= TimeSpan.Zero, null, "window >= TimeSpan.Zero");
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Ensures(Contract.Result<IObservable<TResult>>() != null, null, "Contract.Result<IObservable<TResult>>() != null");
			return null;
		}

		public static IConnectableObservable<TSource> Replay<TSource>(this IObservable<TSource> source, int bufferSize, TimeSpan window, IScheduler scheduler)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(bufferSize >= 0, null, "bufferSize >= 0");
			Contract.Requires(window >= TimeSpan.Zero, null, "window >= TimeSpan.Zero");
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Ensures(Contract.Result<IConnectableObservable<TSource>>() != null, null, "Contract.Result<IConnectableObservable<TSource>>() != null");
			return null;
		}

		public static IObservable<TResult> Replay<TSource, TResult>(this IObservable<TSource> source, Func<IObservable<TSource>, IObservable<TResult>> selector, int bufferSize, TimeSpan window, IScheduler scheduler)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(selector != null, null, "selector != null");
			Contract.Requires(bufferSize >= 0, null, "bufferSize >= 0");
			Contract.Requires(window >= TimeSpan.Zero, null, "window >= TimeSpan.Zero");
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Ensures(Contract.Result<IObservable<TResult>>() != null, null, "Contract.Result<IObservable<TResult>>() != null");
			return null;
		}

		public static IObservable<TSource> Retry<TSource>(this IObservable<TSource> source)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<IObservable<TSource>>() != null, null, "Contract.Result<IObservable<TSource>>() != null");
			return null;
		}

		public static IObservable<TSource> Retry<TSource>(this IObservable<TSource> source, int retryCount)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Requires(retryCount >= 0, null, "retryCount >= 0");
			Contract.Ensures(Contract.Result<IObservable<TSource>>() != null, null, "Contract.Result<IObservable<TSource>>() != null");
			return null;
		}

		public static IObservable<TResult> Return<TResult>(TResult value)
		{
			Contract.Ensures(Contract.Result<IObservable<TResult>>() != null, null, "Contract.Result<IObservable<TResult>>() != null");
			return null;
		}

		public static IObservable<TResult> Return<TResult>(TResult value, IScheduler scheduler)
		{
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Ensures(Contract.Result<IObservable<TResult>>() != null, null, "Contract.Result<IObservable<TResult>>() != null");
			return null;
		}

#if !WINDOWS_PHONE
		public static AsyncSubject<TSource> RunAsync<TSource>(this IObservable<TSource> source, CancellationToken cancellationToken)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<AsyncSubject<TSource>>() != null, null, "Contract.Result<AsyncSubject<TSource>>() != null");
			return null;
		}

		public static AsyncSubject<TSource> RunAsync<TSource>(this IConnectableObservable<TSource> source, CancellationToken cancellationToken)
		{
			Contract.Requires(source != null, null, "source != null");
			Contract.Ensures(Contract.Result<AsyncSubject<TSource>>() != null, null, "Contract.Result<AsyncSubject<TSource>>() != null");
			return null;
		}
#endif
	}
}